#pragma once
/*
异步线程模块
*/
#include "util.hpp"
#include <vector>
#include <thread>
#include <mutex>
#include <atomic>
#include <condition_variable>
#include <functional>
#include "buffer.hpp"

namespace hsl_log
{
    enum class AsyncType
    {
        ASYNC_SAFE,//安全状态，缓冲区满了就阻塞，避免资源耗尽的风险
        ASYNC_UNSAFE,//非安全状态，用于性能测试

    };

    class AsyncLooper
    {
    public:
        using Functor = std::function<void(Buffer &buffer)>; // 定义回调函数类型
        using ptr = std::shared_ptr<AsyncLooper>;            // 智能指针别名
        AsyncLooper(const Functor &cb,AsyncType looper_type = AsyncType::ASYNC_SAFE )
            :_looper_type(looper_type),
            _running(true),
            _looper_callback(cb),
            _thread(std::thread(&AsyncLooper::worker_loop, this)) // 创建工作线程
        {
        }
        ~AsyncLooper() { stop(); } // 析构函数，自动停止处理器
        void stop()
        {
            _running = false;       // 设置运行标志为false
            _pop_cond.notify_all(); // 通知所有等待的线程（唤醒所所有的消费线程）
            _thread.join();         // 等待工作线程结束
        }
        void push(const std::string &msg)
        {
            if (_running == false)
                return;
            {
                std::unique_lock<std::mutex> lock(_mutex);
                // 等待直到缓冲区有足够空间写入新消息
                if(_looper_type ==AsyncType::ASYNC_SAFE)
                    _push_cond.wait(lock, [&]{ return _tasks_push.writeAbleSize() >= msg.size(); });
                // 将消息写入推送缓冲区
                _tasks_push.push(msg.c_str(), msg.size());
            }
            // 唤醒消费者对缓冲区中的数据进行处理
            _pop_cond.notify_all();
        }

    private:
        // 线程入口函数--对消费缓冲区中的数据进行处理，处理完毕之后，初始化缓冲区，交换缓冲区
        void worker_loop()
        {
            while (1)
            {
                // 1.判断生产缓冲区有无数据，有就交换，无就等待
                // “{}”给锁设置生命周期
                {
                    // 加锁
                    std::unique_lock<std::mutex> lock(_mutex);
                    // 检查停止条件：运行标志为false且生产缓冲区为空
                    if (_running == false && _tasks_push.empty())
                    {
                        return;
                    }
                    // 等待直到生产缓冲区有数据或处理器停止
                    _pop_cond.wait(lock, [&]{ return !_tasks_push.empty() || !_running; });
                    // 交换生产缓冲区和消费缓冲区
                    _tasks_push.swap(_tasks_pop);
                }
                // 2.通知生产者线程缓冲区有空闲空间，唤醒生产者
                if(_looper_type ==AsyncType::ASYNC_SAFE)
                    _push_cond.notify_all(); // 通知生产者线程缓冲区有空闲空间
                // 3.被唤醒后，对消费者缓冲区进行处理
                _looper_callback(_tasks_pop); // 调用回调函数处理消费缓冲区中的数据
                // 4.消息处理进行一个重置
                _tasks_pop.reset(); // 重置消费缓冲区
            }
            return;
        }

    private:
        Functor _looper_callback;

    private:
        AsyncType _looper_type;
        std::mutex _mutex;                  // 保护共享数据的互斥锁
        std::atomic<bool> _running;         // 原子布尔值，控制循环是否继续运行
        std::condition_variable _push_cond; // 生产者条件变量，用于等待缓冲区空间
        std::condition_variable _pop_cond;  // 消费者条件变量，用于等待缓冲区数据
        Buffer _tasks_push;                 // 推送/生产缓冲区(生产者写入)
        Buffer _tasks_pop;                  // 弹出/消费缓冲区(消费者读取)
        std::thread _thread;                // 工作线程
    };
}